package com.shushan.accessibility;

import android.accessibilityservice.AccessibilityService;
import android.annotation.TargetApi;
import android.app.ActivityManager;
import android.content.Context;
import android.os.Build;
import android.support.annotation.NonNull;
import android.text.TextUtils;
import android.util.Log;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityNodeInfo;

import com.shushan.shushanbao.BuildConfig;
import com.shushan.ui.CustomDialog;

import java.util.List;

/**
 * @ClassName: AccessibilityOperator
 * @Desciption: 辅助功能操作类
 * @author: yichaohua
 * @date: 2018-07-03
 */

@TargetApi(16)
public class AccessibilityOperator {

    private static final String TAG = "AccessibilityOperator";

    private Context mContext;
    private static AccessibilityOperator mInstance = new AccessibilityOperator();
    private AccessibilityEvent mAccessibilityEvent;
    private AccessibilityService mAccessibilityService;

    private AccessibilityOperator() {
    }

    public static AccessibilityOperator getInstance() {
        return mInstance;
    }

    public void init(Context context) {
        mContext = context;
    }

    public void updateEvent(AccessibilityService service, AccessibilityEvent event) {
        if (service != null && mAccessibilityService == null) {
            mAccessibilityService = service;
        }
        if (event != null) {
            mAccessibilityEvent = event;
        }
    }

    public boolean isServiceRunning() {
        ActivityManager am = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
        List<ActivityManager.RunningServiceInfo> services = am.getRunningServices(Short.MAX_VALUE);
        for (ActivityManager.RunningServiceInfo info : services) {
            if (info.service.getClassName().equals(mContext.getPackageName() + ".AccessibilitySampleService")) {
                return true;
            }
        }
        return false;
    }

    public AccessibilityNodeInfo getRootNodeInfo() {
        AccessibilityEvent curEvent = mAccessibilityEvent;
        AccessibilityNodeInfo nodeInfo = null;
        if (Build.VERSION.SDK_INT >= 16) {
            // 建议使用getRootInActiveWindow，这样不依赖当前的事件类型
            if (mAccessibilityService != null) {
                nodeInfo = mAccessibilityService.getRootInActiveWindow();
                Log.i(TAG,"nodeInfo: " + nodeInfo);

            }
            // 下面这个必须依赖当前的AccessibilityEvent
//            nodeInfo = curEvent.getSource();
        } else {
            nodeInfo = curEvent.getSource();
        }
        return nodeInfo;
    }

    /**
     * 根据Text搜索所有符合条件的节点, 模糊搜索方式
     */
    public List<AccessibilityNodeInfo> findNodesByText(String text) {
        AccessibilityNodeInfo nodeInfo = getRootNodeInfo();
        if (nodeInfo != null) {
           return nodeInfo.findAccessibilityNodeInfosByText(text);
        }
        return null;
    }


    /**
     * 根据View的ID搜索符合条件的节点,精确搜索方式;
     * 这个只适用于自己写的界面，因为ID可能重复
     * api要求18及以上
     * @param viewId
     */
    public List<AccessibilityNodeInfo> findNodesById(String viewId) {
        AccessibilityNodeInfo nodeInfo = getRootNodeInfo();
        if (nodeInfo != null) {
            if (Build.VERSION.SDK_INT >= 18) {
                return nodeInfo.findAccessibilityNodeInfosByViewId(viewId);
            }
        }
        return null;
    }

    public boolean clickByText(String className,String text) {
        if(TextUtils.isEmpty(className) || TextUtils.isEmpty(text)){
            return false;
        }

        List<AccessibilityNodeInfo> nodeInfos = findNodesByText(text);
        for (AccessibilityNodeInfo nodeInfo : nodeInfos){
            Log.i(TAG,"claseName=" + nodeInfo.getClassName());
            if(nodeInfo.getClassName().equals(className)){
               return nodeInfo.performAction(AccessibilityNodeInfo.ACTION_CLICK);
            }
        }

        return false;
    }

    public boolean clickByText(String text) {
        return performClick(findNodesByText(text));
    }

    /**
     * 根据View的ID搜索符合条件的节点,精确搜索方式;
     * 这个只适用于自己写的界面，因为ID可能重复
     * api要求18及以上
     * @param viewId
     * @return 是否点击成功
     */
    public boolean clickById(String viewId) {
        return performClick(findNodesById(viewId));
    }

    private boolean performClick(List<AccessibilityNodeInfo> nodeInfos) {
        if (nodeInfos != null && !nodeInfos.isEmpty()) {
            AccessibilityNodeInfo node;
            for (int i = 0; i < nodeInfos.size(); i++) {
                node = nodeInfos.get(i);
                // 获得点击View的类型
                Log.i(TAG,"View类型：" + node.getClassName());
                // 进行模拟点击
                if (node.isClickable()) {
                    return node.performAction(AccessibilityNodeInfo.ACTION_CLICK);
                }
            }
        }
        return false;
    }

    public boolean clickBackKey() {
        return performGlobalAction(AccessibilityService.GLOBAL_ACTION_BACK);
    }

    private boolean performGlobalAction(int action) {
        return mAccessibilityService.performGlobalAction(action);
    }

    /**
     * 从指定的节点开始向下查找指定类名的组件（深度遍历），在找到一个符合之后就会结束
     *
     * @param nodeInfo   起始节点
     * @param classNames 类名（可多个），每进行一次节点的深度遍历，都会遍历一遍这里传入来的类名，找到了就立即返回
     *
     * @return 最后找到的节点
     */
    @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
    public AccessibilityNodeInfo getNodeByClassName(@NonNull AccessibilityNodeInfo nodeInfo, @NonNull String... classNames) {
        if (nodeInfo.getChildCount() == 0) {
            return null;
        }
        for (int i = 0; i < nodeInfo.getChildCount(); i++) {
            AccessibilityNodeInfo childNodeInfo = nodeInfo.getChild(i);
                StringBuilder sb = new StringBuilder(classNames.length);
                for (String className : classNames) {
                    sb.append(className).append(" ");
                }
                Log.i(TAG,"index: " + i + " className: " + childNodeInfo.getClassName().toString() + "target: " + sb.toString());

            for (String className : classNames) {
                if (childNodeInfo.getClassName().toString().equals(className)) {
                    return childNodeInfo;
                }
            }
            AccessibilityNodeInfo switchOrCheckBoxNodeInfo = getNodeByClassName(childNodeInfo, classNames);
            if (switchOrCheckBoxNodeInfo != null) {
                return switchOrCheckBoxNodeInfo;
            }
        }
        return null;
    }

    /**
     * 从根节点节点开始向下查找指定类名的组件（深度遍历），在找到一个符合之后就会结束
     *
     * @param classNames 类名（可多个），每进行一次节点的深度遍历，都会遍历一遍这里传入来的类名，找到了就立即返回
     *
     * @return 最后找到的节点
     */
    @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
    public AccessibilityNodeInfo getNodeByClassName(@NonNull String... classNames) {
        AccessibilityNodeInfo rootNodeInfo = getRootNodeInfo();
        if (rootNodeInfo == null) {
            return null;
        }
        AccessibilityNodeInfo result = getNodeByClassName(rootNodeInfo, classNames);
        rootNodeInfo.recycle();
        return result;
    }


    public boolean clickListItem(String listId,String itemText,int parentCount){
        if(TextUtils.isEmpty(listId) || TextUtils.isEmpty(itemText) || parentCount < 1){
            return false;
        }

        List<AccessibilityNodeInfo> listNodes = AccessibilityOperator.getInstance()
                .findNodesById(listId);
        if(listNodes != null) {
            List<AccessibilityNodeInfo> textNodes = null;
            for (AccessibilityNodeInfo listNode : listNodes) {
                boolean isBottom = false;
                Log.i(TAG,"listNode=" + listNode);
                do {
                    try {
                        Thread.sleep(500);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    textNodes = listNode.findAccessibilityNodeInfosByText(itemText);
                    if (textNodes == null || textNodes.size() == 0) {
                        if(listNode.isScrollable()){
                            if(!isBottom){
                                if(!listNode.performAction(AccessibilityNodeInfo.ACTION_SCROLL_FORWARD)){
                                    isBottom = true;
                                }
                                continue;
                            }else {
                                if(listNode.performAction(AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD)){
                                    continue;
                                }else {
                                    break;
                                }
                            }

                        }else {
                            break;
                        }
                    } else {
                        for (AccessibilityNodeInfo textNode : textNodes) {
                            Log.i(TAG, "textNode=" + textNode);

                            AccessibilityNodeInfo parentNode = textNode.getParent();
                            Log.i(TAG, "parentNode1=" + parentNode);
                            for (int i = 0; i < (parentCount - 1); i++) {
                                if (parentNode != null) {
                                    parentNode = parentNode.getParent();
                                    Log.i(TAG, "parentNode" + (i + 2) + "=" + parentNode);
                                }
                            }

                            if (parentNode != null && parentNode.isClickable()) {
                                return parentNode.performAction(AccessibilityNodeInfo.ACTION_CLICK);
                            }
                        }

                    }

                } while (textNodes == null || textNodes.size() == 0);

            }
        }

        return false;
    }

    public boolean clickListItem(String itemText,int parentCount){
        if(TextUtils.isEmpty(itemText) || parentCount < 1){
            return false;
        }

        AccessibilityNodeInfo listNode = AccessibilityOperator.getInstance()
                .getNodeByClassName("android.widget.ListView");
        if(listNode != null) {
            List<AccessibilityNodeInfo> textNodes = null;
            boolean isBottom = false;
            Log.i(TAG,"listNode=" + listNode);
            do {
                try {
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                textNodes = listNode.findAccessibilityNodeInfosByText(itemText);
                if (textNodes == null || textNodes.size() == 0) {
                    if(listNode.isScrollable()){
                        if(!isBottom){
                            if(!listNode.performAction(AccessibilityNodeInfo.ACTION_SCROLL_FORWARD)){
                                isBottom = true;
                            }
                            continue;
                        }else {
                            if(listNode.performAction(AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD)){
                                continue;
                            }else {
                                break;
                            }
                        }

                    }else {
                        break;
                    }

                } else {
                    for (AccessibilityNodeInfo textNode : textNodes) {
                        Log.i(TAG, "textNode=" + textNode);

                        AccessibilityNodeInfo parentNode = textNode.getParent();
                        Log.i(TAG, "parentNode1=" + parentNode);
                        for (int i = 0; i < (parentCount - 1); i++) {
                            if (parentNode != null) {
                                parentNode = parentNode.getParent();
                                Log.i(TAG, "parentNode" + (i + 2) + "=" + parentNode);
                            }
                        }

                        if (parentNode != null && parentNode.isClickable()) {
                            return parentNode.performAction(AccessibilityNodeInfo.ACTION_CLICK);
                        }
                    }

                }

            } while (textNodes == null || textNodes.size() == 0);
        }

        return false;
    }

    public boolean clickScrollItem(String itemText,int parentCount){
        if(TextUtils.isEmpty(itemText) || parentCount < 1){
            return false;
        }

        AccessibilityNodeInfo listNode = AccessibilityOperator.getInstance()
                .getNodeByClassName("android.widget.ScrollView");
        if(listNode != null) {
            Log.i(TAG,"listNode=" + listNode);
            boolean isBottom = false;
            List<AccessibilityNodeInfo> textNodes = null;
            do {
                try {
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                textNodes = listNode.findAccessibilityNodeInfosByText(itemText);
                if (textNodes == null || textNodes.size() == 0) {
                    if(listNode.isScrollable()){
                        if(!isBottom){
                            if(!listNode.performAction(AccessibilityNodeInfo.ACTION_SCROLL_FORWARD)){
                                isBottom = true;
                            }
                            continue;
                        }else {
                            if(listNode.performAction(AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD)){
                                continue;
                            }else {
                                break;
                            }
                        }

                    }else {
                        break;
                    }

                } else {
                    for (AccessibilityNodeInfo textNode : textNodes) {
                        Log.i(TAG, "textNode=" + textNode);

                        AccessibilityNodeInfo parentNode = textNode.getParent();
                        Log.i(TAG, "parentNode1=" + parentNode);
                        for (int i = 0; i < (parentCount - 1); i++) {
                            if (parentNode != null) {
                                parentNode = parentNode.getParent();
                                Log.i(TAG, "parentNode" + (i + 2) + "=" + parentNode);
                            }
                        }

                        if (parentNode != null && parentNode.isClickable()) {
                            return parentNode.performAction(AccessibilityNodeInfo.ACTION_CLICK);
                        }
                    }

                }
            } while (textNodes == null || textNodes.size() == 0);
        }

        return false;
    }

    public boolean clickOnlyCustom(String className,boolean isOpen){
        if(TextUtils.isEmpty(className)){
            return false;
        }
        AccessibilityNodeInfo switchNode = getNodeByClassName(className);
        Log.i(TAG,"clickOnlyCustom() switchNode=" + switchNode);
        if(switchNode != null){
            if(switchNode.isChecked() == isOpen){
                return true;
            }else {
                AccessibilityNodeInfo parent = switchNode;
                do{
                    if(parent.isClickable()){
                        return parent.performAction(AccessibilityNodeInfo.ACTION_CLICK);
                    }else {
                        parent = parent.getParent();
                        continue;
                    }
                }while (parent != null);

            }

        }
        return false;
    }

    public boolean clickOnlySwitch(boolean isOpen){
        AccessibilityNodeInfo switchNode = getNodeByClassName("android.widget.Switch");
        Log.i(TAG,"clickOnlySwitch() switchNode=" + switchNode);
        if(switchNode != null){
            if(switchNode.isChecked() == isOpen){
                return true;
            }else {
                return switchNode.performAction(AccessibilityNodeInfo.ACTION_CLICK);
            }

        }
        return false;
    }

    public boolean clickOnlyCheckBox(boolean isOpen){
        AccessibilityNodeInfo switchNode = getNodeByClassName("android.widget.CheckBox");
        if(switchNode != null && (switchNode.isChecked() != isOpen)){
            return switchNode.performAction(AccessibilityNodeInfo.ACTION_CLICK);
        }
        return false;
    }

    public boolean clickListItemSwitch(String listId,String itemText,int parentCount,boolean isOpen){
        if(TextUtils.isEmpty(listId) || TextUtils.isEmpty(itemText) || parentCount < 1){
            return false;
        }

        List<AccessibilityNodeInfo> listNodes = AccessibilityOperator.getInstance()
                .findNodesById(listId);
        if(listNodes != null) {
            List<AccessibilityNodeInfo> textNodes = null;
            for (AccessibilityNodeInfo listNode : listNodes) {
                boolean isBottom = false;
                do {
                    try {
                        Thread.sleep(500);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }

                    textNodes = listNode.findAccessibilityNodeInfosByText(itemText);
                    if (textNodes == null || textNodes.size() == 0) {
                        if(listNode.isScrollable()){
                            if(!isBottom){
                                if(!listNode.performAction(AccessibilityNodeInfo.ACTION_SCROLL_FORWARD)){
                                    isBottom = true;
                                }
                                continue;
                            }else {
                                if(listNode.performAction(AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD)){
                                    continue;
                                }else {
                                    break;
                                }
                            }

                        }else {
                            break;
                        }
                    } else {
                        for (AccessibilityNodeInfo textNode : textNodes) {
                            Log.i(TAG, "textNode=" + textNode);

                            AccessibilityNodeInfo parentNode = textNode.getParent();
                            Log.i(TAG, "parentNode1=" + parentNode);
                            for (int i = 0; i < (parentCount - 1); i++) {
                                if (parentNode != null) {
                                    parentNode = parentNode.getParent();
                                    Log.i(TAG, "parentNode" + (i + 2) + "=" + parentNode);
                                }
                            }

                            if (parentNode != null) {
                                AccessibilityNodeInfo switchNode = getNodeByClassName(parentNode,"android.widget.Switch");
                                Log.i(TAG, "switchNode=" + switchNode);
                                if(switchNode != null){
                                    if((switchNode.isChecked() != isOpen)){
                                        if(parentNode.isClickable()){
                                            return parentNode.performAction(AccessibilityNodeInfo.ACTION_CLICK);
                                        }

                                    }else {
                                        return true;
                                    }

                                }
                            }
                        }

                    }
                } while (textNodes == null || textNodes.size() == 0);

            }
        }

        return false;
    }

    public boolean clickListSwitch(String itemText,int parentCount,boolean isOpen) {
        if (TextUtils.isEmpty(itemText) || parentCount < 1) {
            return false;
        }

        AccessibilityNodeInfo listNode = AccessibilityOperator.getInstance().getNodeByClassName("android.widget.ListView");
        if (listNode != null) {
            List<AccessibilityNodeInfo> textNodes = null;
            boolean isBottom = false;
            do {
                try {
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                textNodes = listNode.findAccessibilityNodeInfosByText(itemText);
                if (textNodes == null || textNodes.size() == 0) {
                    if (listNode.isScrollable()) {
                        if (!isBottom) {
                            if (!listNode.performAction(AccessibilityNodeInfo.ACTION_SCROLL_FORWARD)) {
                                isBottom = true;
                            }
                            continue;
                        } else {
                            if (listNode.performAction(AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD)) {
                                continue;
                            } else {
                                break;
                            }
                        }

                    } else {
                        break;
                    }
                } else {
                    for (AccessibilityNodeInfo textNode : textNodes) {
                        Log.i(TAG, "textNode=" + textNode);

                        AccessibilityNodeInfo parentNode = textNode.getParent();
                        Log.i(TAG, "parentNode1=" + parentNode);
                        for (int i = 0; i < (parentCount - 1); i++) {
                            if (parentNode != null) {
                                parentNode = parentNode.getParent();
                                Log.i(TAG, "parentNode" + (i + 2) + "=" + parentNode);
                            }
                        }

                        if (parentNode != null) {
                            AccessibilityNodeInfo switchNode = getNodeByClassName(parentNode, "android.widget.Switch");
                            Log.i(TAG, "switchNode=" + switchNode);
                            if (switchNode != null && switchNode.isClickable()) {
                                if ((switchNode.isChecked() != isOpen)) {
                                    return switchNode.performAction(AccessibilityNodeInfo.ACTION_CLICK);
                                } else {
                                    return true;
                                }

                            }
                        }
                    }

                }
            } while (textNodes == null || textNodes.size() == 0);

        }

        return false;
    }

    public boolean clickListSwitch(String listId,String itemText,int parentCount,boolean isOpen){
        if(TextUtils.isEmpty(listId) || TextUtils.isEmpty(itemText) || parentCount < 1){
            return false;
        }

        List<AccessibilityNodeInfo> listNodes = AccessibilityOperator.getInstance()
                .findNodesById(listId);
        if(listNodes != null) {
            List<AccessibilityNodeInfo> textNodes = null;
            for (AccessibilityNodeInfo listNode : listNodes) {
                boolean isBottom = false;
                do {
                    try {
                        Thread.sleep(500);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }

                    textNodes = listNode.findAccessibilityNodeInfosByText(itemText);
                    if (textNodes == null || textNodes.size() == 0) {
                        if(listNode.isScrollable()){
                            if(!isBottom){
                                if(!listNode.performAction(AccessibilityNodeInfo.ACTION_SCROLL_FORWARD)){
                                    isBottom = true;
                                }
                                continue;
                            }else {
                                if(listNode.performAction(AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD)){
                                    continue;
                                }else {
                                    break;
                                }
                            }

                        }else {
                            break;
                        }
                    } else {
                        for (AccessibilityNodeInfo textNode : textNodes) {
                            Log.i(TAG, "textNode=" + textNode);

                            AccessibilityNodeInfo parentNode = textNode.getParent();
                            Log.i(TAG, "parentNode1=" + parentNode);
                            for (int i = 0; i < (parentCount - 1); i++) {
                                if (parentNode != null) {
                                    parentNode = parentNode.getParent();
                                    Log.i(TAG, "parentNode" + (i + 2) + "=" + parentNode);
                                }
                            }

                            if (parentNode != null) {
                                AccessibilityNodeInfo switchNode = getNodeByClassName(parentNode,"android.widget.Switch");
                                Log.i(TAG, "switchNode=" + switchNode);
                                if(switchNode != null && switchNode.isClickable()){
                                    if((switchNode.isChecked() != isOpen)){
                                        return switchNode.performAction(AccessibilityNodeInfo.ACTION_CLICK);
                                    }else {
                                        return true;
                                    }

                                }
                            }
                        }

                    }
                } while (textNodes == null || textNodes.size() == 0);

            }
        }

        return false;
    }

    public boolean clickListCustomView(String viewClass,String itemText,int parentCount,boolean isOpen){
        if(TextUtils.isEmpty(viewClass) || TextUtils.isEmpty(itemText) || parentCount < 1){
            return false;
        }

        AccessibilityNodeInfo listNode = AccessibilityOperator.getInstance().getNodeByClassName("android.widget.ListView");
        if(listNode != null) {
            List<AccessibilityNodeInfo> textNodes = null;
            boolean isBottom = false;
            do {
                try {
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                textNodes = listNode.findAccessibilityNodeInfosByText(itemText);
                if (textNodes == null || textNodes.size() == 0) {
                    if(listNode.isScrollable()){
                        if(!isBottom){
                            if(!listNode.performAction(AccessibilityNodeInfo.ACTION_SCROLL_FORWARD)){
                                isBottom = true;
                            }
                            continue;
                        }else {
                            if(listNode.performAction(AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD)){
                                continue;
                            }else {
                                break;
                            }
                        }

                    }else {
                        break;
                    }
                } else {
                    for (AccessibilityNodeInfo textNode : textNodes) {
                        Log.i(TAG, "textNode=" + textNode);

                        AccessibilityNodeInfo parentNode = textNode.getParent();
                        Log.i(TAG, "parentNode1=" + parentNode);
                        for (int i = 0; i < (parentCount - 1); i++) {
                            if (parentNode != null) {
                                parentNode = parentNode.getParent();
                                Log.i(TAG, "parentNode" + (i + 2) + "=" + parentNode);
                            }
                        }

                        if (parentNode != null) {
                            AccessibilityNodeInfo viewNode = getNodeByClassName(parentNode,viewClass);
                            Log.i(TAG, "viewNode=" + viewNode);
                            if(viewNode != null && viewNode.isClickable()){
                                if((viewNode.isChecked() != isOpen)){
                                    return viewNode.performAction(AccessibilityNodeInfo.ACTION_CLICK);
                                }else {
                                    return true;
                                }

                            }
                        }
                    }

                }
            } while (textNodes == null || textNodes.size() == 0);
        }

        return false;
    }

    public boolean clickListSwitch(String listId,String switchId,String itemText,int parentCount,boolean isOpen){
        if(TextUtils.isEmpty(listId) || TextUtils.isEmpty(switchId) || TextUtils.isEmpty(itemText) || parentCount < 1){
            return false;
        }

        List<AccessibilityNodeInfo> listNodes = AccessibilityOperator.getInstance()
                .findNodesById(listId);
        if(listNodes != null) {
            List<AccessibilityNodeInfo> textNodes = null;
            for (AccessibilityNodeInfo listNode : listNodes) {
                boolean isBottom = false;
                do {
                    try {
                        Thread.sleep(500);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }

                    textNodes = listNode.findAccessibilityNodeInfosByText(itemText);
                    if (textNodes == null || textNodes.size() == 0) {
                        if(listNode.isScrollable()){
                            if(!isBottom){
                                if(!listNode.performAction(AccessibilityNodeInfo.ACTION_SCROLL_FORWARD)){
                                    isBottom = true;
                                }
                                continue;
                            }else {
                                if(listNode.performAction(AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD)){
                                    continue;
                                }else {
                                    break;
                                }
                            }

                        }else {
                            break;
                        }
                    } else {
                        for (AccessibilityNodeInfo textNode : textNodes) {
                            Log.i(TAG, "textNode=" + textNode);

                            AccessibilityNodeInfo parentNode = textNode.getParent();
                            Log.i(TAG, "parentNode1=" + parentNode);
                            for (int i = 0; i < (parentCount - 1); i++) {
                                if (parentNode != null) {
                                    parentNode = parentNode.getParent();
                                    Log.i(TAG, "parentNode" + (i + 2) + "=" + parentNode);
                                }
                            }

                            if (parentNode != null) {
                                AccessibilityNodeInfo switchNode = getNodeByClassName(parentNode,switchId);
                                Log.i(TAG, "switchNode=" + switchNode);
                                if(switchNode != null && switchNode.isClickable()){
                                    if((switchNode.isChecked() != isOpen)){
                                        return switchNode.performAction(AccessibilityNodeInfo.ACTION_CLICK);
                                    }else {
                                        return true;
                                    }

                                }
                            }
                        }

                    }
                } while (textNodes == null || textNodes.size() == 0);

            }
        }

        return false;
    }

    public boolean clickListReSwitch(String listId,String itemText,int parentCount,boolean isOpen){
        if(TextUtils.isEmpty(listId) || TextUtils.isEmpty(itemText) || parentCount < 1){
            return false;
        }

        List<AccessibilityNodeInfo> listNodes = AccessibilityOperator.getInstance()
                .findNodesById(listId);
        if(listNodes != null) {
            List<AccessibilityNodeInfo> textNodes = null;
            for (AccessibilityNodeInfo listNode : listNodes) {
                boolean isBottom = false;
                do {
                    try {
                        Thread.sleep(500);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }

                    textNodes = listNode.findAccessibilityNodeInfosByText(itemText);
                    if (textNodes == null || textNodes.size() == 0) {
                        if(listNode.isScrollable()){
                            if(!isBottom){
                                if(!listNode.performAction(AccessibilityNodeInfo.ACTION_SCROLL_FORWARD)){
                                    isBottom = true;
                                }
                                continue;
                            }else {
                                if(listNode.performAction(AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD)){
                                    continue;
                                }else {
                                    break;
                                }
                            }

                        }else {
                            break;
                        }
                    } else {
                        for (AccessibilityNodeInfo textNode : textNodes) {
                            Log.i(TAG, "textNode=" + textNode);

                            AccessibilityNodeInfo parentNode = textNode.getParent();
                            Log.i(TAG, "parentNode1=" + parentNode);
                            for (int i = 0; i < (parentCount - 1); i++) {
                                if (parentNode != null) {
                                    parentNode = parentNode.getParent();
                                    Log.i(TAG, "parentNode" + (i + 2) + "=" + parentNode);
                                }
                            }

                            if (parentNode != null) {
                                AccessibilityNodeInfo switchNode = getNodeByClassName(parentNode,"android.widget.Switch");
                                Log.i(TAG, "switchNode=" + switchNode);
                                if(switchNode != null && switchNode.isClickable()){
                                    if((switchNode.isChecked() != isOpen)){
                                        return switchNode.performAction(AccessibilityNodeInfo.ACTION_CLICK);
                                    }else {
                                        switchNode.performAction(AccessibilityNodeInfo.ACTION_CLICK);
                                        try {
                                            Thread.sleep(1000);
                                        } catch (InterruptedException e) {
                                            e.printStackTrace();
                                        }
                                        return switchNode.performAction(AccessibilityNodeInfo.ACTION_CLICK);
                                    }

                                }
                            }
                        }

                    }
                } while (textNodes == null || textNodes.size() == 0);

            }
        }

        return false;
    }

    public boolean clickListCheckBox(String itemText,int parentCount,boolean isOpen){
        if(TextUtils.isEmpty(itemText) || parentCount < 1){
            return false;
        }

        AccessibilityNodeInfo listNode = AccessibilityOperator.getInstance().getNodeByClassName("android.widget.ListView");
        if(listNode != null) {
            List<AccessibilityNodeInfo> textNodes = null;
            boolean isBottom = false;
            do {
                try {
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                textNodes = listNode.findAccessibilityNodeInfosByText(itemText);
                if (textNodes == null || textNodes.size() == 0) {
                    if(listNode.isScrollable()){
                        if(!isBottom){
                            if(!listNode.performAction(AccessibilityNodeInfo.ACTION_SCROLL_FORWARD)){
                                isBottom = true;
                            }
                            continue;
                        }else {
                            if(listNode.performAction(AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD)){
                                continue;
                            }else {
                                break;
                            }
                        }

                    }else {
                        break;
                    }
                } else {
                    for (AccessibilityNodeInfo textNode : textNodes) {
                        Log.i(TAG, "textNode=" + textNode);

                        AccessibilityNodeInfo parentNode = textNode.getParent();
                        Log.i(TAG, "parentNode1=" + parentNode);
                        for (int i = 0; i < (parentCount - 1); i++) {
                            if (parentNode != null) {
                                parentNode = parentNode.getParent();
                                Log.i(TAG, "parentNode" + (i + 2) + "=" + parentNode);
                            }
                        }

                        if (parentNode != null) {
                            AccessibilityNodeInfo switchNode = getNodeByClassName(parentNode,"android.widget.CheckBox");
                            Log.i(TAG, "switchNode=" + switchNode);
                            if(switchNode != null && switchNode.isClickable()){
                                if((switchNode.isChecked() != isOpen)){
                                    return switchNode.performAction(AccessibilityNodeInfo.ACTION_CLICK);
                                }else {
                                    return true;
                                }

                            }
                        }
                    }

                }

            } while (textNodes == null || textNodes.size() == 0);

        }

        return false;
    }

    public void getRecycleView(){
        if (mAccessibilityService != null && BuildConfig.DEBUG) {
            Log.i(TAG, "==>==>==>==>==>==>==>==>==>==>==>==>==>==>==>");
            AccessibilityNodeInfo rowNode = mAccessibilityService.getRootInActiveWindow();
            if (rowNode == null) {
                Log.i(TAG, "noteInfo is　null");
                return;
            } else {
                recycle(rowNode);
            }
            Log.i(TAG, "<==<==<==<==<==<==<==<==<==<==<==<==<==<==<==");
        }else {
            Log.e(TAG,"mAccessibilityService is null");
        }


    }

    public void recycle(AccessibilityNodeInfo info) {
        if (info.getChildCount() == 0) {
            Log.i(TAG, "child widget----------------------------" + info.getClassName());
            Log.i(TAG, "showDialog:" + info.canOpenPopup());
            Log.i(TAG, "Text：" + info.getText());
            Log.i(TAG, "windowId:" + info.getWindowId());
            Log.i(TAG, "isClickable:" + info.isClickable());
        } else {
            for (int i = 0; i < info.getChildCount(); i++) {
                if(info.getChild(i)!=null){
                    recycle(info.getChild(i));
                }
            }
        }
    }
}
